/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.entity.methods;

import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.utils.ExpressionUtils;
import com.inspur.edp.cef.entity.condition.FilterCondition;
import com.inspur.edp.cef.generator.DotNetToJavaStringHelper;
import com.inspur.edp.cef.generator.repository.base.assemblerGenerator.DataTypeAssemblerGenCtx;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import lombok.var;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;

import java.util.ArrayList;
import java.util.Arrays;

public class GetDefaultSortConditionMethodGenerator extends ClassMethodGenerator
{
	private static final String ConditionVarName = "condition";
	protected DataTypeAssemblerGenCtx assGenCtx;
	public GetDefaultSortConditionMethodGenerator(DataTypeAssemblerGenCtx assGenCtx)
	{
		this.assGenCtx = assGenCtx;
	}

	private IGspCommonObject getCommonObject() { return (IGspCommonObject)assGenCtx.getDataType(); }
	@Override
	protected Block buildMethodBody()
	{
		String filterCondition = getCommonObject().getFilterCondition();
		Block block = ast.newBlock();
		if (DotNetToJavaStringHelper.isNullOrEmpty(filterCondition))
		{
			block.statements().add(getReturnNullStatement());
			return block;
		}
		ArrayList<Statement> statements = getFilterStatements(filterCondition);
		block.statements().addAll(statements);
		return block;
	}
	private ReturnStatement getReturnNullStatement()
	{
		return ExpressionUtils.getReturnNullStatement(ast);

	}
	private ArrayList<Statement>  getFilterStatements(String filterCondition)
	{
		ArrayList<Statement> statements = new ArrayList<Statement>();
		Statement conditionStatement = getConditionStatement(filterCondition);
		statements.add(conditionStatement);

		ReturnStatement serializeStatement = getSerializeStatement();
		statements.add(serializeStatement);

		return statements;
	}

	private Statement getConditionStatement(String filterCondition)
	{
		var frag = ast.newVariableDeclarationFragment();
		frag.setName(ast.newSimpleName(ConditionVarName));
		var value = ast.newStringLiteral();
		value.setLiteralValue(filterCondition);
		frag.setInitializer(value);

		var statement = ast.newVariableDeclarationStatement(frag);
		statement.setType(ast.newSimpleType(ast.newSimpleName("String")));
		return statement;

//		return SyntaxFactory.LocalDeclarationStatement(
//				SyntaxFactory.VariableDeclaration(
//						SyntaxFactory.IdentifierName("var")).
//						WithVariables(SyntaxFactory.SingletonSeparatedList(
//								SyntaxFactory.VariableDeclarator(
//										SyntaxFactory.Identifier(ConditionVarName))
//										.WithInitializer(SyntaxFactory.EqualsValueClause(
//												SyntaxFactory.LiteralExpression(
//														SyntaxKind.StringLiteralExpression,
//														SyntaxFactory.Literal(filterCondition)))))));
	}

	private ReturnStatement  getSerializeStatement()
	{
		var returnStatement = ast.newReturnStatement();
		var methodInvocation = ast.newMethodInvocation();
		methodInvocation.setName(ast.newSimpleName("readValue"));

		var classCreation = ast.newClassInstanceCreation();
		classCreation.setType(ast.newSimpleType(ast.newSimpleName("ObjectMapper")));
		methodInvocation.setExpression(classCreation);

		methodInvocation.arguments().add(ast.newSimpleName(ConditionVarName));

		var arg2 = ast.newMethodInvocation();
		arg2.setName(ast.newSimpleName("getClass"));
		var argCreation = ast.newClassInstanceCreation();

		var agrType = ast.newParameterizedType(
				ast.newSimpleType(ast.newSimpleName("ArrayList"))
		);
		agrType.typeArguments().add(
				ast.newSimpleType(ast.newSimpleName("FilterCondition"))
		);
		argCreation.setType(agrType);
		arg2.setExpression(argCreation);
		methodInvocation.arguments().add(arg2);
		returnStatement.setExpression(methodInvocation);


		return returnStatement;

//		return SyntaxFactory.ReturnStatement(SyntaxFactory.BinaryExpression(
//				SyntaxKind.AsExpression, SyntaxFactory.InvocationExpression(
//						SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
//								TypeUtils.getTypeSyntax(JsonConvert.class),
//								SyntaxFactory.IdentifierName("DeserializeObject"))).
//						WithArgumentList(SyntaxFactory.ArgumentList(SyntaxFactory.<ArgumentSyntax>SeparatedList(
//								new SyntaxNodeOrToken[] { SyntaxFactory.Argument(
//										SyntaxFactory.IdentifierName(ConditionVarName)),
//										SyntaxFactory.Token(SyntaxKind.CommaToken),
//										SyntaxFactory.Argument(SyntaxFactory.TypeOfExpression(
//												TypeUtils.getTypeSyntax(java.util.ArrayList<FilterCondition>.class)))
//								}))), TypeUtils.getTypeSyntax(java.util.ArrayList<FilterCondition>.class)));
	}


	@Override
	protected ArrayList<Modifier.ModifierKeyword>  getAccessModifiers()
	{
		return new ArrayList<Modifier.ModifierKeyword>(Arrays.asList(
				new Modifier.ModifierKeyword[] { Modifier.ModifierKeyword.PROTECTED_KEYWORD }));
	}

	@Override
	protected boolean getIsOverride() {
		return true;
	}

	@Override
	protected String  getMethodName() { return "getDefaultFilterCondition";
	}

	@Override
	protected ArrayList<ParameterInfo>  getParameterCollection()
	{
		return new ArrayList<ParameterInfo>();
	}

	@Override
	protected TypeInfo getReturnType() {
		//TODO: caf暂不支持, 主动加import
		assGenCtx.getRepoGenCtx().addImport(ArrayList.class.getName());
		assGenCtx.getRepoGenCtx().addImport(FilterCondition.class.getName());
		var typeInfo = new TypeInfo(ArrayList.class);
		typeInfo.setIsParameterizedType(true);
		var arg = new TypeInfo(FilterCondition.class);
		typeInfo.getArguments().add(arg);

		return typeInfo;
	}
}
